package com.qf.rbac2202.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.qf.rbac2202.sys.entity.SysMenu;
import com.qf.rbac2202.sys.entity.SysRoleMenu;
import com.qf.rbac2202.sys.entity.SysUserRole;
import com.qf.rbac2202.sys.mapper.SysMenuMapper;
import com.qf.rbac2202.sys.service.ISysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.rbac2202.sys.service.ISysRoleMenuService;
import com.qf.rbac2202.sys.service.ISysUserRoleService;
import com.qf.rbac2202.utils.Constants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单管理 服务实现类
 * </p>
 *
 * @author dong_
 * @since 2022-10-28
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

    @Autowired
    ISysUserRoleService sysUserRoleService;

    @Autowired
    ISysRoleMenuService sysRoleMenuService;

    @Autowired
    SysMenuMapper sysMenuMapper;

    @Override
    public List<SysMenu> queryAllMenuByUserId(Long userId) {
        // 准备返回值
        ArrayList<SysMenu> sysMenus = new ArrayList<>();
        // 先查询用户角色信息
        List<SysUserRole> list = sysUserRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId,userId));
        // 再根据角色信息查询菜单信息,查 role_menu
        list.forEach(sysUserRole -> {
            List<SysRoleMenu> roleMenus = sysRoleMenuService.list(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId,sysUserRole.getRoleId()));
            roleMenus.forEach(sysRoleMenu -> {
                SysMenu sysMenu = this.getById(sysRoleMenu.getMenuId());
                sysMenus.add(sysMenu);
            });
        });
        return sysMenus;
    }

    @Override
    public List< String > queryAllPerms( Long userId ) {
        List< SysMenu > belongUserMenuList=getBelongUserMenuList( userId );

        List<String> collect = belongUserMenuList.stream().filter(sysMenu -> StringUtils.isNotBlank(sysMenu.getPerms())).map( sysMenu -> {
            return sysMenu.getPerms();
        }).distinct().collect(Collectors.toList());
        return collect;
    }


    public SysMenu getBoss(Long userId) {

        List< SysMenu > belongUserMenuList=getBelongUserMenuList( userId );
        SysMenu usersecondMenuList=getUsersecondMenuList( belongUserMenuList );


        return usersecondMenuList;

    }

    public List<SysMenu> getBelongUserMenuList(Long userId){
        //获取所有菜单中的对象
        List<SysMenu> allmenus = sysMenuMapper.selectList(null);

        //根据用户id查询去角色用户id表中查询所有符合对象的对象并将其转化为角色id的集合
        List< SysUserRole > roleandUsers=sysUserRoleService.list( new QueryWrapper<SysUserRole>( ).eq( "user_id",userId ) );
        List< Long > roleIds=roleandUsers.stream( ).map( s->s.getRoleId( ) ).collect( Collectors.toList( ) );

        //根据角色id去中间表里查询所有的menuids
        //所有中间表的对象的集合并将其转化为菜单id的集合
        List<SysRoleMenu> sysRoleMenus=new ArrayList<SysRoleMenu>( );
        for(Long roleId: roleIds) {
            List< SysRoleMenu > roleMenus=sysRoleMenuService.list( new QueryWrapper< SysRoleMenu >( ).eq( "role_id",roleId ) );
            sysRoleMenus.addAll( roleMenus );
        }
        List< Long > menuIds=sysRoleMenus.stream( ).map( s->s.getMenuId( ) ).collect( Collectors.toList( ) );


        //遍历所有的菜单中的对象
        //生成符合当前角色的菜单对象
        ArrayList< SysMenu > newSysMenus=new ArrayList<>( );
        for(SysMenu allmenu: allmenus) {
            if(menuIds.contains( allmenu.getMenuId() )){
                newSysMenus.add(allmenu  );
            }
        }

        return newSysMenus;
    }

    public SysMenu getUsersecondMenuList(List<SysMenu> list){
        for(SysMenu sysMenu: list) {
            List< SysMenu > sysMenus=new ArrayList<>( );

            sysMenu.setList(  sysMenus);
            for(SysMenu menu: list) {
                if(menu.getParentId()==sysMenu.getMenuId()){

                    sysMenu.getList().add( menu );
                }
            }

        }
        return list.get( 0 );
    }

    @Override
    public List<SysMenu> getUserMenuList(Long userId) {
        //系统管理员，拥有最高权限
        if(userId == Constants.SUPER_ADMIN){
            // 查询所有菜单信息
            List<SysMenu> allmenu = this.list();
            // 组织菜单层级关系
            return orgnizeByParentId(0l,allmenu);
        }

        //用户菜单列表
        List<SysMenu> menuList = this.queryAllMenuByUserId(userId);
        return orgnizeByParentId(0l,menuList);
    }

    private List<SysMenu> orgnizeByParentId(Long parentId, List<SysMenu> allmenu) {
        // 筛选出parentId对应的菜单
        List<SysMenu> menuList = allmenu.stream().filter(sysMenu -> sysMenu.getParentId().equals(parentId)).collect(Collectors.toList());
        // 给menuList中的所有菜单挂子菜单l
        if(menuList.size()>0){
            return populateChildMenu(menuList,allmenu);
        }else {
            return menuList;
        }
    }

    private List<SysMenu> populateChildMenu(List<SysMenu> list, List<SysMenu> allmenu) {
        list.forEach(sysMenu -> {
            // 判断当前菜单有没有子菜单，如果没有，则返回
            List<SysMenu> childList = findChildMenu(sysMenu,allmenu);
            if (childList.size()>0) {
                // 如果有子菜单，则查找出所有子菜单，对子菜单进行寻找子菜单的递归调用
                populateChildMenu(childList,allmenu);
                // 挂子菜单到当前菜单
                sysMenu.setList(childList);
            }
        });
        return list;
    }

    private List<SysMenu> findChildMenu(SysMenu sysMenu, List<SysMenu> allmenu) {
        List<SysMenu> collect = allmenu.stream().filter(sysMenu1 -> sysMenu1.getParentId().equals(sysMenu.getMenuId())).collect(Collectors.toList());
        return collect;
    }
}
